package com.tanhua.app.Service;

import cn.hutool.core.collection.CollUtil;
import com.tanhua.app.exception.BusinessException;
import com.tanhua.app.interceptor.UserHolder;
import com.tanhua.commons.utils.Constants;
import com.tanhua.config.template.OssTemplate;
import com.tanhua.dubbo.api.MovementApi;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.VisitorsApi;
import com.tanhua.model.mongo.Movement;
import com.tanhua.model.mongo.Visitors;
import com.tanhua.model.pojo.UserInfo;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.MovementsVo;
import com.tanhua.model.vo.PageResult;
import com.tanhua.model.vo.VisitorsVo;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class MovementsService {
    @DubboReference
    private MovementApi movementApi;
    @DubboReference
    private UserInfoApi userInfoApi;
    @Autowired
    private OssTemplate ossTemplate;
    @DubboReference
    private VisitorsApi visitorsApi;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private UserFreezeService userFreezeService;
    @Autowired
    private MqMessageService mqMessageService;

    //    动态-发布
    public void publishMovement(Movement movement, MultipartFile[] imageContent) throws Exception {
        Long userId = UserHolder.getUserId();
        if (userId != null) {
            userFreezeService.checkUserFreeze(userId,"3");
        }
        if (StringUtils.isBlank(movement.getTextContent())) {
            throw new BusinessException(ErrorResult.contentError());
        }

        ArrayList<String> medias = new ArrayList<>();
        for (MultipartFile multipartFile : imageContent) {
            String url = ossTemplate.upload(multipartFile.getOriginalFilename(), multipartFile.getInputStream());
            medias.add(url);
        }
        movement.setMedias(medias);
        movement.setUserId(UserHolder.getUserId());
        String movementId = movementApi.publish(movement);
        mqMessageService.sendAudiMessage(movementId);
        mqMessageService.sendLogMessage(userId,"0201","movement",movementId);

    }

    //    我的动态
    public PageResult<MovementsVo> findByUserId(Long userId, Integer page, Integer pageSize) {
        if (userId == null) {
            userId = UserHolder.getUserId();
        }
        PageResult<Movement> pageResult = movementApi.findPageByUserId(userId, page, pageSize);
        if (pageResult.getItems() == null || pageResult.getItems().isEmpty()) {
            return new PageResult<>(page, pageSize, 0, null);
        }
        UserInfo userInfo = userInfoApi.findById(userId);
        List<MovementsVo> collect = pageResult.getItems().stream()
                .map(item -> MovementsVo.init(userInfo, item)).collect(Collectors.toList());
        return new PageResult<>(pageResult.getPage(), pageResult.getPagesize(), pageResult.getCounts(), collect);
    }

    //    好友动态
    public PageResult<MovementsVo> findFriendMovements(Integer page, Integer pageSize) {
        List<Movement> movementList = movementApi.findFriendMovements(UserHolder.getUserId(), page, pageSize);
        if (movementList == null || movementList.isEmpty()) {
            return new PageResult<>(page, pageSize, 0, null);
        }
        return getPageResult(page, pageSize, movementList);
    }

    private PageResult<MovementsVo> getPageResult(Integer page, Integer pageSize, List<Movement> movementList) {
        List<Long> ids = movementList.stream().map(Movement::getUserId).collect(Collectors.toList());
        List<UserInfo> userInfos = userInfoApi.findByUserIds(ids);
        Map<Long, UserInfo> userInfoMap = userInfos.stream()
                .collect(Collectors.toMap(UserInfo::getId, Function.identity()));
        ArrayList<MovementsVo> vos = new ArrayList<>();
        for (Movement movement : movementList) {
            UserInfo userInfo = userInfoMap.get(movement.getUserId());
            if (userInfo != null) {
                MovementsVo init = MovementsVo.init(userInfo, movement);

                String key = Constants.MOVEMENTS_INTERACT_KEY + movement.getId().toHexString();
                String hashKey = Constants.MOVEMENT_LIKE_HASHKEY + UserHolder.getUserId();
                if (stringRedisTemplate.opsForHash().hasKey(key, hashKey)) {
                    init.setHasLiked(1);
                }

                hashKey = Constants.MOVEMENT_LOVE_HASHKEY + UserHolder.getUserId();
                if (stringRedisTemplate.opsForHash().hasKey(key, hashKey)) {
                    init.setHasLoved(1);
                }

                vos.add(init);
            }
        }
        return new PageResult<>(page, pageSize, 0, vos);
    }

    //    推荐动态
    public PageResult<MovementsVo> findRecommendMovements(Integer page, Integer pagesize) {
        String value = stringRedisTemplate.opsForValue().get(Constants.MOVEMENTS_RECOMMEND + UserHolder.getUserId());
        List<Movement> movements = new ArrayList<>();
        if (StringUtils.isBlank(value)) {
            movements = movementApi.randamMovements(pagesize);
        } else {
            String[] pids = value.split(",");
            if ((page - 1) * pagesize < pids.length) {
                List<Long> pidList = Arrays.stream(pids)
                        .skip((page - 1) * pagesize)
                        .limit(pagesize)
                        .map(pid -> Long.parseLong(pid))
                        .collect(Collectors.toList());
                movements = movementApi.findMovementsByPids(pidList);
            }
        }
        return getPageResult(page, pagesize, movements);
    }

    //    单条动态
    public MovementsVo findById(String id) {
        Movement movement = movementApi.findById(id);
        if (movement == null) {
            return null;
        }
        UserInfo userInfo = userInfoApi.findById(movement.getUserId());
        mqMessageService.sendLogMessage(UserHolder.getUserId(),"0202","movement",id);
        return MovementsVo.init(userInfo, movement);
    }

    //    谁看过我
    public List<VisitorsVo> queryVisitorsList() {
        String key = Constants.VISITORS_USER;
        String hashKey = UserHolder.getUserId().toString();
        String value = (String) stringRedisTemplate.opsForHash().get(key, hashKey);
        Long date = StringUtils.isBlank(value) ? null : Long.parseLong(value);

        List<Visitors> list = visitorsApi.queryMyVisitors(date,UserHolder.getUserId());
        if(CollUtil.isEmpty(list)){
            return new ArrayList<>();
        }

        List<Long> ids = list.stream().map(Visitors::getUserId).collect(Collectors.toList());
        List<UserInfo> userInfos = userInfoApi.findByUserIds(ids);
        Map<Long, UserInfo> map = userInfos.stream().collect(Collectors.toMap(UserInfo::getId, Function.identity()));
        List<VisitorsVo> vos = new ArrayList<>();
        for (Visitors visitors : list) {
            UserInfo userInfo = map.get(visitors.getUserId());
            if (userInfo != null) {
                VisitorsVo vo = VisitorsVo.init(userInfo, visitors);
                vos.add(vo);
            }
        }
        return vos;
    }
}
